/**
  ******************************************************************************
  * @文件名           : bsp_usart.c
  * @作者             : citunhk
  * @功能介绍         : USART串口配置及发送驱动
  *	@日期             : 2022.10.31
  ******************************************************************************
  * @注意
  *
  * 本文件中不应调用上层文件
  *
  ******************************************************************************
  *更改记录
  *日期 修改人 修改内容
  *
  *
  *
  ******************************************************************************
  */
/* Private includes ----------------------------------------------------------*/
#include "bsp_usart.h"
#include "stm32g0xx_ll_usart.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

uint8_t gUSART1_DMARx_HMI_buffer[RS232_SLAVER_DMARX_NUM];
uint8_t gUSART2_DMARx_Master_buffer[RS485_MASTER_DMARX_NUM];
uint8_t gUSART3_DMARx_Slaver_buffer[RS485_SLAVER_DMARX_NUM];

///**
//  * @author Edward
//  * @changedate 2022.04.25
//  * @brief LL库的USART串口发送字符串
//  */
//
//void BSP_Usart1_SendStr(char *sendBuf)
//{
//  while(*sendBuf)
//  {
//	while(LL_USART_IsActiveFlag_TC(USART1)!=1);//等待发送完成
//	LL_USART_TransmitData8(USART1,(uint8_t)(*sendBuf & (uint8_t)0xff));//发送数据
//	sendBuf++;
//  }
//}
//
/**
  * @author Edward
  * @changedate 2022.04.25
  * @brief LL库的USART串口发送数据  作为从机与用户设备通讯相关
  */

/**
* @函数名	USART1_Config
* @功能	    USART1串口中断及DMA配置
* @入口参数	无
* @返回值	无
*/
void USART1_Config(void)
{
    LL_USART_EnableIT_IDLE(USART1);  //使能串口空闲中断
    LL_DMA_SetMemoryAddress(DMA1,LL_DMA_CHANNEL_2,(uint32_t)gUSART1_DMARx_HMI_buffer);  //接收目标地址
    LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_2,200);  //设置DMA接收数据长度
    LL_DMA_SetPeriphAddress(DMA1,LL_DMA_CHANNEL_2,(uint32_t)&(USART1->RDR));  //设置外设地址
    LL_DMA_EnableIT_TC(DMA1,LL_DMA_CHANNEL_2);  //使能DMA完成通道
    LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_2);  //使能通道
    LL_USART_EnableDMAReq_RX(USART1);  //使能串口DMA接收
}

/**
* @函数名	USART2_Config
* @功能	    USART2串口中断及DMA配置
* @入口参数	无
* @返回值	无
*/
void USART2_Config(void)
{
    LL_GPIO_ResetOutputPin(RS485_R_T2_GPIO_Port, RS485_R_T2_Pin);
    LL_USART_EnableIT_IDLE(USART2);  //使能串口空闲中断
    LL_DMA_SetMemoryAddress(DMA1,LL_DMA_CHANNEL_3,(uint32_t)gUSART2_DMARx_Master_buffer);  //接收目标地址
    LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_3,200);  //设置DMA接收数据长度
    LL_DMA_SetPeriphAddress(DMA1,LL_DMA_CHANNEL_3,(uint32_t)&(USART2->RDR));  //设置外设地址
    LL_DMA_EnableIT_TC(DMA1,LL_DMA_CHANNEL_3);  //使能DMA完成通道
    LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_3);  //使能通道
    LL_USART_EnableDMAReq_RX(USART2);  //使能串口DMA接收
}

/**
* @函数名	USART3_Config
* @功能	    USART3串口中断及DMA配置
* @入口参数	无
* @返回值	无
*/
void USART3_Config(void)
{
    LL_GPIO_ResetOutputPin(RS485_R_T3_GPIO_Port, RS485_R_T3_Pin);
	LL_USART_EnableIT_IDLE(USART3);  //使能串口空闲中断
    LL_DMA_SetMemoryAddress(DMA1,LL_DMA_CHANNEL_4,(uint32_t)gUSART3_DMARx_Slaver_buffer);  //接收目标地址
    LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_4,200);  //设置DMA接收数据长度
    LL_DMA_SetPeriphAddress(DMA1,LL_DMA_CHANNEL_4,(uint32_t)&(USART3->RDR));  //设置外设地址
    LL_DMA_EnableIT_TC(DMA1,LL_DMA_CHANNEL_4);  //使能DMA完成通道
    LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_4);  //使能通道
    LL_USART_EnableDMAReq_RX(USART3);  //使能串口DMA接收
}

/**
* @函数名	USART3_Config_BaudRate
* @功能	    USART3串口波特率更改
* @入口参数	mode 串口波特率 0 9600
*                          1 19200
* @返回值	无
*/
void USART3_Config_BaudRate(uint8_t mode)
{
	uint32_t bauerate = 9600;

	LL_USART_InitTypeDef USART_InitStruct = {0};

	if(mode == 0)
	{
		bauerate = 9600;
	}
	else if(mode == 1)
	{
		bauerate = 19200;
	}

	  LL_USART_Disable(USART3);

	  USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
	  USART_InitStruct.BaudRate = bauerate;
	  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
	  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
	  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
	  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
	  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
	  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
	  LL_USART_Init(USART3, &USART_InitStruct);
	  LL_USART_ConfigAsyncMode(USART3);

	  LL_USART_Enable(USART3);

	  /* Polling USART3 initialisation */
	  while((!(LL_USART_IsActiveFlag_TEACK(USART3))) || (!(LL_USART_IsActiveFlag_REACK(USART3))))
	  {
	  }
}

/**
* @函数名	USART3_Config_Switch
* @功能	    USART3串口配置切换
* @入口参数	mode 串口模式  0 9600 校验无 数据位8 停止位1
*                          1 9600 校验偶校验 数据位7 停止位1
* @返回值	无
*/
void USART3_Config_Switch(uint8_t mode, uint32_t baudRate)
{
	LL_USART_InitTypeDef USART_InitStruct = {0};

	LL_USART_Disable(USART3);

	USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
	USART_InitStruct.BaudRate = baudRate;//波特率
	USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
	USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
	USART_InitStruct.Parity = (mode == 1)? LL_USART_PARITY_EVEN: LL_USART_PARITY_NONE;//检验方式
	USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
	USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
	USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
	LL_USART_Init(USART3, &USART_InitStruct);
	LL_USART_ConfigAsyncMode(USART3);

	LL_USART_Enable(USART3);

	/* Polling USART3 initialisation */
	while((!(LL_USART_IsActiveFlag_TEACK(USART3))) || (!(LL_USART_IsActiveFlag_REACK(USART3))))
	{
	}
}

/**
* @函数名	BSP_Usart_SendU8
* @功能	    串口发送无符号8位数组驱动函数
* @入口参数	USARTx 发送串口 USART1
*                          USART2
*                          USART3
*           sendBuf 需要发送数据的首地址
*           Size 需要发送的数据个数
* @返回值	无
*/
void BSP_Usart_SendU8(USART_TypeDef *USARTx,uint8_t *sendBuf,uint16_t Size)
{
  uint16_t i;
  uint8_t j;
	for(i=0;i<Size;i++)
	{
		j=0;
		//while(LL_USART_IsActiveFlag_TC(USARTx)!=1);//等待发送完成
		while(LL_USART_IsActiveFlag_TC(USARTx)!=1)
		{
			j++;
			if(j>12800)//等待发送完成
			return;
		}
		LL_USART_TransmitData8(USARTx,(uint8_t)(*sendBuf & (uint8_t)0xff));//发送数据
		sendBuf++;
	}
}

/**
* @函数名	RS485_Master_Bus
* @功能	    主机收发使能
* @入口参数	TxEnable RS485芯片收发状态 RS485_Master_Tx
*                                     RS485_Master_Rx
* @返回值	无
*/
void BSP_RS485_Master(uint8_t TxEnable)
{
	if(TxEnable==RS485_Master_Tx)
	{
		LL_GPIO_SetOutputPin(RS485_R_T2_GPIO_Port, RS485_R_T2_Pin);
	}else if(TxEnable==RS485_Master_Rx)
	{
		LL_GPIO_ResetOutputPin(RS485_R_T2_GPIO_Port, RS485_R_T2_Pin);
	}
}

/**
* @函数名	BSP_RS485_Slaver
* @功能	    从机收发使能
* @入口参数	TxEnable RS485芯片收发状态 RS485_Slaver_Tx
*                                     RS485_Slaver_Rx
* @返回值	无
*/
void BSP_RS485_Slaver(uint8_t TxEnable)
{
	if(TxEnable==RS485_Slaver_Tx)
	{
		LL_GPIO_SetOutputPin(RS485_R_T3_GPIO_Port, RS485_R_T3_Pin);
	}else if(TxEnable==RS485_Slaver_Rx)
	{
		LL_GPIO_ResetOutputPin(RS485_R_T3_GPIO_Port, RS485_R_T3_Pin);
	}
}

///**************** (C) COPYRIGHT EdwardYang *************END OF FILE****/
